﻿using Entity;
using Microsoft.AspNetCore.Http;
using System;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using XingWeiDaWMSProject.IRepository;
using XingWeiDaWMSProject.IService;
using Microsoft.Extensions.Logging;

namespace XingWeiDaWMSProject.Service
{
    public class SysOrgUserManagementService : ISysOrgUserManagementService
    {
        private readonly ISysOrgUserManagementRepository _userRepository;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly ILogger<SysOrgUserManagementService> _logger;

        public SysOrgUserManagementService(
            ISysOrgUserManagementRepository userRepository,
            IHttpContextAccessor httpContextAccessor,
            ILogger<SysOrgUserManagementService> logger)
        {
            _userRepository = userRepository;
            _httpContextAccessor = httpContextAccessor;
            _logger = logger;
        }

        // 性别编码转文字（空值处理）
        private string ConvertSexCodeToText(string sexCode)
        {
            if (string.IsNullOrEmpty(sexCode)) return "未知";
            return sexCode switch
            {
                "1" => "男",
                "2" => "女",
                _ => "未知"
            };
        }

        // 性别文字转编码（空值处理）
        private string ConvertSexTextToCode(string sexText)
        {
            if (string.IsNullOrEmpty(sexText)) return "0";
            return sexText switch
            {
                "男" => "1",
                "女" => "2",
                _ => "0"
            };
        }

        private string Md5Encrypt(string input)
        {
            if (string.IsNullOrEmpty(input)) return string.Empty;
            using (MD5 md5 = MD5.Create())
            {
                byte[] inputBytes = Encoding.UTF8.GetBytes(input); // 必须是UTF-8编码
                byte[] hashBytes = md5.ComputeHash(inputBytes);
                StringBuilder sb = new StringBuilder();
                foreach (byte b in hashBytes) sb.Append(b.ToString("X2")); // "X2" 表示大写32位
                return sb.ToString();
            }
        }

        // 根据账号查询用户（含性别转文字）
        public async Task<SysOrgUserManagement> GetUserByAccountAsync(string userAccount)
        {
            if (string.IsNullOrEmpty(userAccount)) return null;
            var user = await _userRepository.GetByUserAccountAsync(userAccount);
            if (user != null) user.Sex = ConvertSexCodeToText(user.Sex);
            return user;
        }

        // 获取当前登录账号（修复：未登录返回null，而非"system"）
        public string GetCurrentUserAccount()
        {
            if (_httpContextAccessor?.HttpContext == null) return null;
            try
            {
                // 从Session获取（优先）
                var session = _httpContextAccessor.HttpContext.Session;
                if (session != null && session.TryGetValue("LoginUserName", out byte[] sessionBytes))
                {
                    string account = Encoding.UTF8.GetString(sessionBytes).Trim();
                    if (!string.IsNullOrEmpty(account)) return account;
                }
                // 从Identity/Claims获取
                var identity = _httpContextAccessor.HttpContext.User.Identity;
                if (identity?.IsAuthenticated == true && !string.IsNullOrEmpty(identity.Name))
                    return identity.Name;
                var claim = _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.Name);
                return claim?.Value;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取当前用户账号异常");
                return null;
            }
        }

        // 更新用户基本信息
        public async Task<bool> UpdateUserAsync(SysOrgUserManagement user)
        {
            if (user == null || user.UserId <= 0) return false;
            user.Sex = ConvertSexTextToCode(user.Sex);
            user.UpdateBy = GetCurrentUserAccount();
            user.UpdateTime = DateTime.Now;
            return await _userRepository.UpdateAsync(user);
        }

        /// <summary>
        /// 验证密码（核心：加密后与数据库比对）
        /// </summary>
        public async Task<bool> VerifyPasswordAsync(string userAccount, string password)
        {
            if (string.IsNullOrEmpty(userAccount) || string.IsNullOrEmpty(password))
            {
                _logger.LogWarning("VerifyPasswordAsync：账号或密码为空（账号：{Account}）", userAccount);
                return false;
            }

            try
            {
                // 加密输入的密码（与登录逻辑完全一致）
                string encryptedPwd = Md5Encrypt(password);
                // 查询数据库中存储的密码哈希（新增日志，方便比对）
                string dbPassword = await _userRepository.GetPasswordByAccountAsync(userAccount);
                _logger.LogInformation(
                    "VerifyPasswordAsync：原密码加密后={EncryptedPwd}，数据库存储密码={DbPwd}（账号：{Account}）",
                    encryptedPwd, dbPassword, userAccount);

                // 比对加密后的值与数据库存储的哈希
                bool isMatch = await _userRepository.VerifyPasswordAsync(userAccount, encryptedPwd);
                return isMatch;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "VerifyPasswordAsync异常（账号：{Account}）", userAccount);
                return false;
            }
        }

        /// <summary>
        /// 修改密码（完整流程：校验→验证原密码→加密新密码→更新）
        /// </summary>
        public async Task<string> ChangePasswordAsync(string userAccount, string oldPassword, string newPassword)
        {
            // 1. 基础参数校验
            if (string.IsNullOrEmpty(userAccount))
            {
                _logger.LogWarning("ChangePasswordAsync：用户账号为空");
                return "登录已失效，请重新登录";
            }
            if (string.IsNullOrEmpty(oldPassword))
            {
                _logger.LogWarning("ChangePasswordAsync：原密码为空（账号：{Account}）", userAccount);
                return "原密码不能为空";
            }
            if (string.IsNullOrEmpty(newPassword))
            {
                _logger.LogWarning("ChangePasswordAsync：新密码为空（账号：{Account}）", userAccount);
                return "新密码不能为空";
            }
            if (oldPassword == newPassword)
            {
                _logger.LogWarning("ChangePasswordAsync：新密码与原密码一致（账号：{Account}）", userAccount);
                return "新密码不能与原密码相同";
            }
            if (newPassword.Length < 6) // 新增：密码长度校验（可根据需求调整）
            {
                _logger.LogWarning("ChangePasswordAsync：新密码长度不足6位（账号：{Account}）", userAccount);
                return "新密码长度不能少于6位";
            }

            // 2. 查询用户是否存在且可用
            var user = await _userRepository.GetByUserAccountAsync(userAccount);
            if (user == null)
            {
                _logger.LogWarning("ChangePasswordAsync：用户不存在（账号：{Account}）", userAccount);
                return "用户不存在或已被删除";
            }
            if (user.Status != "1") // 假设"1"表示启用状态
            {
                _logger.LogWarning("ChangePasswordAsync：用户已被禁用（账号：{Account}，状态：{Status}）", userAccount, user.Status);
                return "账号已被禁用，无法修改密码";
            }

            // 3. 验证原密码（核心步骤）
            bool isOldPwdValid = await VerifyPasswordAsync(userAccount, oldPassword);
            if (!isOldPwdValid)
            {
                _logger.LogWarning("ChangePasswordAsync：原密码错误（账号：{Account}）", userAccount);
                return "原密码错误，请重新输入";
            }

            // 4. 加密新密码并更新数据库
            try
            {
                string encryptedNewPwd = Md5Encrypt(newPassword);
                string updateBy = GetCurrentUserAccount() ?? userAccount; // 兜底：用当前账号作为更新人
                DateTime updateTime = DateTime.Now;

                bool isUpdateSuccess = await _userRepository.ChangePasswordAsync(
                    userAccount, encryptedNewPwd, updateBy, updateTime);

                if (isUpdateSuccess)
                {
                    _logger.LogInformation("ChangePasswordAsync：密码修改成功（账号：{Account}）", userAccount);
                    return "success";
                }
                else
                {
                    _logger.LogError("ChangePasswordAsync：数据库更新失败（账号：{Account}）", userAccount);
                    return "密码更新失败，请稍后重试";
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "ChangePasswordAsync异常（账号：{Account}）", userAccount);
                return "系统异常，请联系管理员";
            }
        }
        /// <summary>
        /// 原有无参方法（兼容旧调用，内部调用有参方法）
        /// </summary>
        public async Task<int> GetCurrentUserOrganizationIdAsync()
        {
            // 先按原有逻辑获取用户账号
            string currentAccount = GetCurrentUserAccount();
            if (string.IsNullOrEmpty(currentAccount))
            {
                _logger.LogError("GetCurrentUserOrganizationIdAsync：当前用户未登录或账号为空");
                throw new Exception("未获取到当前登录用户，请重新登录");
            }
            // 调用新增的有参方法（复用逻辑）
            return await GetCurrentUserOrganizationIdAsync(currentAccount);
        }

        /// <summary>
        /// 新增有参方法：用Controller传递的用户账号查组织ID
        /// </summary>
        public async Task<int> GetCurrentUserOrganizationIdAsync(string userAccount)
        {
            // 1. 校验传入的用户账号（Controller层已兜底，但服务层再校验更安全）
            if (string.IsNullOrEmpty(userAccount))
            {
                _logger.LogError("GetCurrentUserOrganizationIdAsync：传入的用户账号为空");
                throw new Exception("未获取到当前登录用户，请重新登录");
            }

            // 2. 用传入的userAccount查询用户（不再自己获取用户）
            var user = await _userRepository.GetByUserAccountAsync(userAccount);
            if (user == null)
            {
                _logger.LogError("GetCurrentUserOrganizationIdAsync：未查询到用户（账号：{Account}）", userAccount);
                throw new Exception($"用户「{userAccount}」不存在或已被删除");
            }

            // 3. 校验组织ID有效性（逻辑不变）
            if (!user.OrganizationId.HasValue || user.OrganizationId <= 0)
            {
                _logger.LogError("GetCurrentUserOrganizationIdAsync：用户未关联组织（账号：{Account}）", userAccount);
                throw new Exception($"用户「{userAccount}」未配置组织信息，请联系管理员");
            }

            _logger.LogInformation("GetCurrentUserOrganizationIdAsync：用户组织ID获取成功（账号：{Account}，组织ID：{OrgId}）",
                userAccount, user.OrganizationId);
            return user.OrganizationId.Value;
        }
        /// <summary>
        /// 修改为：获取所有用户（去掉角色过滤）
        /// </summary>
        public async Task<List<SysOrgUserManagement>> GetAllOperatorsAsync()
        {
            try
            {
                _logger.LogInformation("开始查询所有用户");
                // 调用仓库层的“获取所有用户”方法（无需角色过滤）
                var allUsers = await _userRepository.GetAllAsync();

                // 处理空值（确保返回空列表而非null）
                var result = allUsers ?? new List<SysOrgUserManagement>();
                _logger.LogInformation($"所有用户查询完成，共{result.Count}条记录");
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询所有用户时发生异常");
                return new List<SysOrgUserManagement>(); // 异常时返回空列表
            }
        }
    }
}